package cn.pzhu.pserson.controller;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.pzhu.pserson.model.Prize;
import cn.pzhu.pserson.util.ExcelFormatUtil;
import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import cn.pzhu.pserson.util.ResponseUtil;
import cn.pzhu.pserson.service.IAppointmentService;
import cn.pzhu.pserson.model.Appointment;
import cn.pzhu.pserson.dto.AppointmentDTO;
import cn.pzhu.pserson.dto.LimitShowDTO;
import org.springframework.web.servlet.ModelAndView;


@Controller
@RequestMapping("/appointment")
public class AppointmentController {
    private  final  static Logger logger = LoggerFactory.getLogger(LogoController.class);
    @Autowired
    private IAppointmentService appointmentService;

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public ModelAndView list(Model model,
                             @Validated
        LimitShowDTO limitShowDTO, BindingResult errors) {

        Map<String, Object> result = new HashMap<String, Object>();

        List<Map<String, Object>> appointmentList = appointmentService.loadMaps(null, null, null, null, limitShowDTO.getPageNum(), limitShowDTO.getPageSize());
        long count = appointmentService.count();

        result.put("rows", appointmentList);
        result.put("total", count);


        model.addAttribute("size", count);
        model.addAttribute("list", appointmentList);
        model.addAttribute("pageNum", limitShowDTO.getPageNum());
        model.addAttribute("nums", Math.ceil(Double.parseDouble(count+ "") / Double.parseDouble(limitShowDTO.getPageSize() + "")));

        return new ModelAndView("/appointment/list");
    }

    @CrossOrigin
    @RequestMapping(value = "/export", method = RequestMethod.GET, produces = {"text/plain;charset=utf-8","text/html;charset=utf-8"}             )
    @ResponseBody
    public ResponseEntity<byte[]> export(
            @Validated
                    LimitShowDTO limitShowDTO, BindingResult errors, HttpServletResponse response, HttpServletRequest request) throws ParseException {


        List<Appointment>  appointments = appointmentService.loadModels(null,new String[]{},null,null,-1,-1);

        try {
            return buildResponseEntity(export(appointments), "预约记录表-燕园理想城.xls");
        }catch (Exception e){
            e.printStackTrace();
            logger.error(">>>>>>>>>>导出excel 异常，原因为：" + e.getMessage());
        }
        return null;
    }

    public ResponseEntity<byte[]> buildResponseEntity(InputStream is, String name) throws Exception {
        logger.info(">>>>>>>>>>>>>>>>>>>>开始下载文件>>>>>>>>>>");
        if (this.logger.isDebugEnabled())
            this.logger.debug("download: " + name);
        HttpHeaders header = new HttpHeaders();
        String fileSuffix = name.substring(name.lastIndexOf('.') + 1);
        fileSuffix = fileSuffix.toLowerCase();

        Map<String, String> arguments = new HashMap<String, String>();
        arguments.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        arguments.put("xls", "application/vnd.ms-excel");

        String contentType = arguments.get(fileSuffix);
        header.add("Content-Type", (StringUtils.hasText(contentType) ? contentType : "application/x-download"));
        if(is!=null && is.available()!=0){
            header.add("Content-Length", String.valueOf(is.available()));
            header.add("Content-Disposition", "attachment;filename*=utf-8'zh_cn'" + URLEncoder.encode(name, "UTF-8"));
            byte[] bs = IOUtils.toByteArray(is);
            logger.info(">>>>>>>>>>>>>>>>>>>>结束下载文件-有记录>>>>>>>>>>");
            logger.info(">>>>>>>>>>结束导出excel>>>>>>>>>>");
            return new ResponseEntity<>(bs, header, HttpStatus.OK);
        }else{
            String string="数据为空";
            header.add("Content-Length", "0");
            header.add("Content-Disposition", "attachment;filename*=utf-8'zh_cn'" + URLEncoder.encode(name, "UTF-8"));
            logger.info(">>>>>>>>>>>>>>>>>>>>结束下载文件-无记录>>>>>>>>>>");
            logger.info(">>>>>>>>>>结束导出excel>>>>>>>>>>");
            return new ResponseEntity<>(string.getBytes(), header, HttpStatus.OK);
        }
    }

    private InputStream export(List<Appointment> list) {
        logger.info(">>>>>>>>>>>>>>>>>>>>开始进入导出方法>>>>>>>>>>");
        ByteArrayOutputStream output = null;
        InputStream inputStream1 = null;
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);// 保留1000条数据在内存中
        SXSSFSheet sheet = wb.createSheet();
        // 设置报表头样式
        CellStyle header = ExcelFormatUtil.headSytle(wb);// cell样式
        CellStyle content = ExcelFormatUtil.contentStyle(wb);// 报表体样式

        // 每一列字段名
        String[] strs = new String[] { "客户姓名", "手机号",  "录入时间"};

        // 字段名所在表格的宽度
        int[] ints = new int[] { 5000, 5000, 5000 };

        // 设置表头样式
        ExcelFormatUtil.initTitleEX(sheet, header, strs, ints);
        logger.info(">>>>>>>>>>>>>>>>>>>>表头样式设置完成>>>>>>>>>>");

        if (list != null && list.size() > 0) {
            logger.info(">>>>>>>>>>>>>>>>>>>>开始遍历数据组装单元格内容>>>>>>>>>>");
            for (int i = 0; i < list.size(); i++) {
                Appointment user = list.get(i);
                SXSSFRow row = sheet.createRow(i + 1);
                int j = 0;

                SXSSFCell cell = row.createCell(j++);
                cell.setCellValue(user.getName());
                cell.setCellStyle(content);

                cell = row.createCell(j++);
                cell.setCellValue(user.getPhone() + "");
                cell.setCellStyle(content);

                cell = row.createCell(j++);
                cell.setCellValue(user.getAttr1());
                cell.setCellStyle(content);
            }
            logger.info(">>>>>>>>>>>>>>>>>>>>结束遍历数据组装单元格内容>>>>>>>>>>");
        }
        try {
            output = new ByteArrayOutputStream();
            wb.write(output);
            inputStream1 = new ByteArrayInputStream(output.toByteArray());
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (output != null) {
                    output.close();
                    if (inputStream1 != null)
                        inputStream1.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return inputStream1;
    }

    @CrossOrigin
    @RequestMapping(value = "/saveInfo", method = RequestMethod.POST, produces = {"text/plain;charset=utf-8","text/html;charset=utf-8"}             )
    @ResponseBody
    public ResponseEntity<String> saveInfo(
            @Validated
                    LimitShowDTO limitShowDTO, BindingResult errors, HttpServletResponse response, HttpServletRequest request) {
        Map<String, Object> result = new HashMap<String, Object>();

        String openid = request.getParameter("openid");
        String name = request.getParameter("name");
        String phone = request.getParameter("phone");

        Appointment appointment = new Appointment();

        appointment.setName(name);
        appointment.setOpenid(openid);
        appointment.setPhone(phone);
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        appointment.setAttr1(f.format(new Date()));

        Boolean bool = appointmentService.save(appointment);

        return ResponseUtil.getResEntityForGet(bool);
    }


    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public ResponseEntity<String> show(@PathVariable("id") Integer id) {
        Map<String, Object> appointmentModel = appointmentService.findMap(id);

        return ResponseUtil.getResEntityForGetAndJson(appointmentModel);
    }

    @RequestMapping(value = "", method = RequestMethod.POST)
    public ResponseEntity<String> create(
        @Validated
        AppointmentDTO appointmentDTO, BindingResult errors) {
        if(errors.hasErrors())
            return ResponseUtil.getResponseEntityWhenInvalidReqParams();

        Appointment appointmentModel = appointmentDTO.toModel();

        return ResponseUtil.getResEntityForPPP(appointmentService.save(appointmentModel));
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public ResponseEntity<String> update(@PathVariable("id") Integer id,
        @Validated
        AppointmentDTO appointmentDTO, BindingResult errors) {

        Appointment appointmentModel = appointmentDTO.toModel();
        appointmentModel.setId(id);
        return ResponseUtil.getResEntityForPPP(appointmentService.update(appointmentModel));
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public ResponseEntity<String> destory(@PathVariable("id") Integer id) {
        return ResponseUtil.getResEntityForDel(appointmentService.delete(id));
    }

    @RequestMapping(value = "/deletes", method = RequestMethod.DELETE)
    public ResponseEntity<String> deletes(@RequestParam("primaryKeys") Integer[] primaryKeys) {
        return ResponseUtil.getResEntityForDel(appointmentService.batchDelete(primaryKeys));
    }
}
